﻿Imports QuantumBitDesigns.Core
Imports System.ComponentModel
Imports System.Collections.ObjectModel
Imports System.Threading

Public Class AvailableVisable(Of TItem)
    Implements INotifyPropertyChanged

    Private m_Dispatcher As Windows.Threading.Dispatcher
    Private m_Container As IAvailableVisable(Of TItem)
    Private m_ItemsAvailable As ObservableList(Of TItem)
    Private m_IsLoading As Boolean = False
    Private m_ItemsVisable As ObservableList(Of TItem)
    Private m_IsSyncing As Boolean = False
    Private m_ResyncRequired As Boolean = False

    Public Sub New(ByVal dispatcher As Windows.Threading.Dispatcher, ByVal container As IAvailableVisable(Of TItem))
        m_Dispatcher = dispatcher
        m_Container = container
        m_ItemsAvailable = New ObservableList(Of TItem)(m_Dispatcher)
        m_ItemsVisable = New ObservableList(Of TItem)(m_Dispatcher)
    End Sub

#Region " INotifyPropertyChanged "

    Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

    Public Sub OnPropertyChanged(ByVal PropertyName As String)
        If Not m_Dispatcher.CheckAccess Then
            m_Dispatcher.Invoke(New Action(Of String)(AddressOf OnPropertyChanged), PropertyName)
        End If
        If Not PropertyChangedEvent Is Nothing Then
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(PropertyName))
        End If
    End Sub

#End Region

    Public Property IsLoading() As Boolean
        Get
            Return m_IsLoading
        End Get
        Private Set(ByVal value As Boolean)
            If Not value = m_IsLoading Then
                m_IsLoading = value
                OnPropertyChanged("IsLoading")
            End If
        End Set
    End Property

    Public ReadOnly Property ItemsAvailable() As ObservableCollection(Of TItem)
        Get
            Return m_ItemsAvailable.ObservableCollection
        End Get
    End Property

    Public Sub Refresh()
        LoadItemsAvailable()
    End Sub

    Private Sub LoadItemsAvailable()
        If Not IsLoading Then
            IsLoading = True
            Dim x As New Action(AddressOf LoadItemsAvailable_Async)
            x.BeginInvoke(New AsyncCallback(AddressOf LoadItemsAvailable_AsyncComplete), Nothing)
        End If
    End Sub

    Private Sub LoadItemsAvailable_Async()
        Dim lM_ContainerLoadAvailableCallLogs_Async As List(Of TItem) = m_Container.LoadItemsAvailable_Async
        m_ItemsAvailable.Sync(lM_ContainerLoadAvailableCallLogs_Async)
        IsLoading = False
    End Sub

    Private Sub LoadItemsAvailable_AsyncComplete()
        SyncVisable()
    End Sub

    Public Property IsSyncing() As Boolean
        Get
            Return m_IsSyncing
        End Get
        Private Set(ByVal value As Boolean)
            If Not value = m_IsSyncing Then
                m_IsSyncing = value
                OnPropertyChanged("IsSyncing")
            End If
        End Set
    End Property

    Public ReadOnly Property ItemsVisable() As ObservableCollection(Of TItem)
        Get
            Return m_ItemsVisable.ObservableCollection
        End Get
    End Property

    Public Sub ReSync()
        SyncVisable()
    End Sub

    Private Sub SyncVisable()
        If Not IsSyncing Then
            IsSyncing = True
            System.Threading.ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf SyncVisable_Async))
        End If
    End Sub

    Private Sub SyncVisable_Async()
        Dim result As IEnumerable(Of TItem) = m_Container.SyncItemsVisable_Async(m_ItemsAvailable)
        m_ItemsAvailable.Sync(result)
        IsSyncing = False
    End Sub

End Class
